Skip to content

test(producer): extract frameDirMaxIndexCache to its own module and pin cross-job isolation#381

Merged
vanceingalls merged 1 commit intomainfrom
vance/frame-dir-cache-isolation-tests
Apr 23, 2026
Merged

test(producer): extract frameDirMaxIndexCache to its own module and pin cross-job isolation#381
vanceingalls merged 1 commit intomainfrom
vance/frame-dir-cache-isolation-tests

Conversation

@vanceingalls
Copy link
Copy Markdown
Collaborator

@vanceingalls vanceingalls commented Apr 21, 2026

Summary

Extract the frameDirMaxIndexCache from a private module-scoped Map inside renderOrchestrator.ts into its own frameDirCache.ts module, then add a 11-test bun:test suite that pins the cross-job isolation contract added in Chunk 5B.

Why

Chunk 9E of plans/hdr-followups.md. The cache lived as a private Map inside renderOrchestrator.ts, which made the cross-job isolation contract from Chunk 5B impossible to unit-test directly. Extracting it both makes the contract testable and reduces orchestrator complexity slightly.

What changed

  • New packages/producer/src/services/frameDirCache.ts exposes getMaxFrameIndex / clearMaxFrameIndex / getMaxFrameIndexCacheSize (plus a test-only __resetMaxFrameIndexCacheForTests helper). Behavior is unchanged: callers still get the same module-scoped sharing inside a job, and renderOrchestrator's outer finally still clears every entry it registered so the cache cannot grow monotonically across renders.
  • renderOrchestrator.ts: imports the new helpers, drops the unused readdirSync import, updates inline comments, and replaces two frameDirMaxIndexCache.delete sites with clearMaxFrameIndex.
  • New frameDirCache.test.ts (bun:test, 11 tests) covering:
    • Reading the max index from a populated directory.
    • Ignoring filenames that don't match frame_NNNN.png (wrong ext, wrong prefix, wrong case, double extension, empty index group, same-named subdirectory).
    • Empty- and missing-directory paths returning 0 and being cached.
    • Intra-job invariant: subsequent readdir mutations not observed once cached.
    • clearMaxFrameIndex forcing a re-read; returns false for paths that were never cached.
    • Per-directory isolation when multiple directories are registered.
    • The cross-job contract from Chunk 5B: cache empty between well-behaved jobs, doesn't grow monotonically across 20 simulated renders with 3 HDR videos each (steady-state cache size stays at 3), and a buggy job that forgets to clear leaks exactly its own entries rather than affecting unrelated jobs.

Test plan

  • frameDirCache.test.ts 11/11 pass.
  • Existing producer tests unchanged.
  • Behavior preserved: same module-scoped sharing inside a job, same outer-finally eviction.

Stack

Chunk 9E of plans/hdr-followups.md. Test-driven extraction; complements Chunk 5B.

Copy link
Copy Markdown
Collaborator Author

vanceingalls commented Apr 21, 2026

This stack of pull requests is managed by Graphite. Learn more about stacking.

@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from 91f129b to fe8fd9b Compare April 21, 2026 20:48
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch 2 times, most recently from ae2d4a7 to 5f4e626 Compare April 21, 2026 20:54
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from fe8fd9b to 253cf29 Compare April 21, 2026 20:54
@vanceingalls vanceingalls marked this pull request as ready for review April 21, 2026 20:57
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from 253cf29 to faa7890 Compare April 21, 2026 22:37
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from 5f4e626 to cbdf78d Compare April 21, 2026 22:37
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from faa7890 to e4eb138 Compare April 22, 2026 01:16
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from cbdf78d to ca75d84 Compare April 22, 2026 01:16
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch 2 times, most recently from 143a1db to 6ece916 Compare April 23, 2026 02:58
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from c76bbb2 to 1cb6854 Compare April 23, 2026 02:58
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from 6ece916 to e638a99 Compare April 23, 2026 03:21
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from 1cb6854 to adfcf6f Compare April 23, 2026 03:21
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from e638a99 to 5fb85c5 Compare April 23, 2026 03:42
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from adfcf6f to 56d9997 Compare April 23, 2026 03:43
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from 5fb85c5 to d84c3ea Compare April 23, 2026 04:50
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from 56d9997 to b8fa66f Compare April 23, 2026 04:51
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from d84c3ea to 4b68ca4 Compare April 23, 2026 05:10
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from b8fa66f to d9a7c43 Compare April 23, 2026 05:11
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from 4b68ca4 to 4be516a Compare April 23, 2026 05:46
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from d9a7c43 to dc034ec Compare April 23, 2026 05:46
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from 4be516a to 5a225bf Compare April 23, 2026 06:07
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from dc034ec to 39201e6 Compare April 23, 2026 06:07
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from 5a225bf to c7fcca8 Compare April 23, 2026 06:59
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch 2 times, most recently from cdb1508 to dea33f9 Compare April 23, 2026 15:33
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch 2 times, most recently from bc1bac0 to 7d56ccc Compare April 23, 2026 16:34
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch 2 times, most recently from 46d8211 to d3d28cc Compare April 23, 2026 16:35
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch 2 times, most recently from 5262779 to 49ca88b Compare April 23, 2026 17:39
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from d3d28cc to f30f52c Compare April 23, 2026 17:39
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from 49ca88b to 9a0e79c Compare April 23, 2026 18:12
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from f30f52c to a54a246 Compare April 23, 2026 18:13
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from 9a0e79c to dc46219 Compare April 23, 2026 18:42
…in cross-job isolation

Chunk 9E. The frame-directory max-index cache lived as a private
module-scoped Map inside renderOrchestrator.ts, which made the cross-job
isolation contract added in Chunk 5B impossible to unit-test directly.

Extract the cache into packages/producer/src/services/frameDirCache.ts
behind getMaxFrameIndex / clearMaxFrameIndex / getMaxFrameIndexCacheSize
(plus a test-only __resetMaxFrameIndexCacheForTests helper). Behavior is
unchanged: callers still get the same module-scoped sharing inside a
job, and renderOrchestrator's outer finally still clears every entry it
registered so the cache cannot grow monotonically across renders.

renderOrchestrator now imports the new helpers, drops the unused
readdirSync import, and updates the inline comments to point at the new
module. Two cleanup sites that previously called
frameDirMaxIndexCache.delete now call clearMaxFrameIndex.

Add frameDirCache.test.ts (bun:test) with 11 tests covering:
  - reading the max index from a populated directory
  - ignoring filenames that do not match frame_NNNN.png (wrong ext,
    wrong prefix, wrong case, double extension, empty index group, and
    a same-named subdirectory)
  - empty- and missing-directory paths returning 0 and being cached
  - the intra-job invariant that subsequent readdir mutations are not
    observed once a directory has been cached
  - clearMaxFrameIndex forcing a re-read and returning false for paths
    that were never cached
  - per-directory isolation when multiple directories are registered
  - the cross-job contract from Chunk 5B: the cache is empty between
    well-behaved jobs, does not grow monotonically across 20 simulated
    renders with 3 HDR videos each (steady-state cache size stays at 3),
    and a buggy job that forgets to clear leaks exactly its own entries
    rather than affecting unrelated jobs.

Made-with: Cursor
Copy link
Copy Markdown
Collaborator Author

Merge activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants